package com.example.leetdemo.finash;

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Stack;

public class Solution1705 {

    public int eatenApplesType1(int[] apples, int[] days) {
        Stack<int[]> stack = new Stack<>();
        int i = 0;
        int count = 0;
        while (true) {
            putApples(apples, days, i, stack);
            if (stack.size() > 0) {
                int[] newApple = stack.pop();
                if (newApple[1] > 0 && newApple[0] >= i) {
                    newApple[1] = newApple[1] - 1;
                    if (newApple[1] > 0) {
                        stack.push(newApple);
                    }
                    count++;
                } else {
                    for (int k = i + 1; k < days.length; k++) {
                        putApples(apples, days, k, stack);
                    }
                    i = days.length;
                }
            }
            i++;
            if (i > days.length && stack.size() == 0) {
                break;
            }
        }
        return count;
    }

    private void putApples(int[] apples, int[] days, int i, Stack<int[]> stack) {
        if (i < days.length) {
            // 将新的苹果放到栈中 并保证stack.pop获取到的都是最快过期的苹果
            int day = days[i] + i - 1;
            if (stack.size() != 0) {
                Stack<int[]> stack1 = new Stack<>();
                while (stack.size() > 0) {
                    int[] temp = stack.pop();
                    if (temp[0] > day) {
                        // day 比 本次取得苹果 先过期
                        stack.push(temp);
                        stack.push(new int[] {day, apples[i]});
                        break;
                    } else if (temp[0] < day) {
                        // day 比 本次取得苹果 新鲜
                        stack1.push(temp);
                        if (stack.size() == 0) {
                            stack.push(new int[] {day, apples[i]});
                            break;
                        }
                    } else {
                        // 和本次取得苹果一样新鲜
                        temp[1] += apples[i];
                        stack.push(temp);
                        break;
                    }
                }
                while (stack1.size() > 0) {
                    stack.push(stack1.pop());
                }
            } else {
                stack.push(new int[] {day, apples[i]});
            }
        }

        while (stack.size() > 0) {
            int[] p = stack.peek();
            if (p[0] < i) {
                stack.pop();
            } else {
                break;
            }
        }
    }

    public static void main(String[] args) {
        Solution1705 solution1705 = new Solution1705();
        System.err.println(solution1705.eatenApples(new int[] {3,1,1,0,0,2}, new int[] {3,1,1,0,0,2}));

        PriorityQueue<int[]> priorityQueue = new PriorityQueue<>(Comparator.comparingInt(o -> o[0]));

    }


    public int eatenApples(int[] apples, int[] days) {
        int count = 0;
        int size = apples.length;
        PriorityQueue<int[]> priorityQueue = new PriorityQueue<>(Comparator.comparingInt(o -> o[0]));
        for (int i = 0; i < size; i++) {
            priorityQueue.add(new int[] {days[i] + i, apples[i]});
            int a = priorityQueue.size();
            while (a > 0) {
                if (priorityQueue.peek()[0] <= i || priorityQueue.peek()[1] == 0) {
                    priorityQueue.remove();
                } else {
                    break;
                }
                a--;
            }
            if (priorityQueue.size() > 0) {
                count++;
                priorityQueue.peek()[1]--;
                if (priorityQueue.peek()[1] == 0) {
                    priorityQueue.remove();
                }
            }
        }
        int day = size;
        while (priorityQueue.size() > 0) {
            count += Math.min(priorityQueue.peek()[1], priorityQueue.peek()[0] - day);
            day += Math.min(priorityQueue.peek()[1], priorityQueue.peek()[0] - day);
            priorityQueue.remove();
        }
        return count;
    }



}
